package com.fingard.dsp.bank.directbank.jhbank01;

import org.apache.commons.lang3.StringUtils;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.directbank.jhbank01.utils.PublickeyEncript;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.MD5SaltHelper;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.File;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Created by F on 2018/8/27.
 */
public class JHBANK01BatPayRec extends JHBANK01Base implements IBatPayRec {
    private static final String INSERTRECEIPT = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,TRANSDATE,REQBATCHNO,REQSEQID,BANKREQSEQID,STATE,ISFINISHED)" +
            " VALUES (?,?,?,?,?,?,?,?);";
    private static final String SELECTRECEIPT = "SELECT BANKREQSEQID,REQSEQID,STATE,ISFINISHED,RESERVE1 FROM REQSEQIDMAPPING WHERE REQBATCHNO=?;";
    private static final String UPDATERECEIPT = "UPDATE REQSEQIDMAPPING SET STATE=?,ISFINISHED=1,RESERVE1=? WHERE REQSEQID=? AND REQBATCHNO=?;";

    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        String respCode = "";
        String respInfo = "";
        Connection conn = null;
        try {
            conn = FGBiz.getLocalDbConn();
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "0";
            retAts.respInfo = "获取数据库连接失败，请检查数据库配置是否正确";
            retAts.transState = "dba_exp";
            retAts.reqSeqID = p_req1988.reqBatchNO;
            retAts.payInfoCode = "dba_exp";
            retAts.writeRetToATS();
            return retAts;
        }
        String failpath = getBankConfig().getValueAsString("PayfailPath") + File.separator + p_req1988.reqBatchNO + ".txt";
        StringBuilder reqseqIdContent = new StringBuilder();
        while (p_req1988.readRecord()) {
            try {
                XmlTextWriter xmlTextWriter = new XmlTextWriter();
                JHBANK01Header header = new JHBANK01Header();
                header.userid = bankFront.operator;
                String nodeNo = getBankConfig().getValueAsString("nodeNo");
                header.brchno = nodeNo;
                header.servtp = "";
                header.prcscd = "QCB01";
                writeCommenHeader(xmlTextWriter, header);
                XElement body = new XElement("Body", "");
                body.addChild(new XElement("tellNo", bankFront.operator));//操作员号
                body.addChild(new XElement("nodeNo", nodeNo));// 财政局标示
                body.addChild(new XElement("tranCode", "QCB01"));//交易代码
                //系统简称 6为日期+8位流水
                String transferFlowNo;
                if ("88883".equals(nodeNo)) {
                    transferFlowNo = "pj" + Format.Date6Format.format(Format.Date10Format.parse(p_req1988.payDate));
                } else if ("88884".equals(nodeNo)) {
                    transferFlowNo = "dy" + Format.Date6Format.format(Format.Date10Format.parse(p_req1988.payDate));
                } else {
                    throw new Exception("nodeno属性标签配置有误:" + nodeNo);
                }
                int flowLength = p_req1988.readedDetail.askNumber.length();
                if (flowLength > 8) {
                    transferFlowNo = transferFlowNo + p_req1988.readedDetail.askNumber.substring(flowLength - 8);
                } else {
                    transferFlowNo = transferFlowNo + StringUtils.leftPad(p_req1988.readedDetail.askNumber, 8, "0");
                }
                //插入数据库
                try {
                    String urid = UUID.randomUUID().toString().replaceAll("-", "");
                    int i = JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{urid, "JHBANK01", p_req1988.payDate, p_req1988.reqBatchNO, p_req1988.readedDetail.askNumber, transferFlowNo, "", "0"});
                    if (i == 0) {
                        respCode = "-1";
                        WriteBankLogLn("插入数据库失败，批次编号：" + p_req1988.readedDetail.askNumber);
                        reqseqIdContent.append(p_req1988.readedDetail.askNumber + "|");
                        continue;
                    }
                } catch (Exception ex) {
                    respCode = "-1";
                    WriteBankLogLn(ex);
                    reqseqIdContent.append(p_req1988.readedDetail.askNumber + "|");
                    continue;
                }
                body.addChild(new XElement("transferFlowNo", transferFlowNo));// 财政流水号
                body.addChild(new XElement("payAccount", p_req1988.readedDetail.payAct));// 付款账号
                body.addChild(new XElement("payAccountNm", p_req1988.readedDetail.payName));// 付款方户名
                String payAcctBrn = getBankConfig().getValueAsString("org");
                body.addChild(new XElement("payAcctBrn", payAcctBrn));// 付款账户开户机构
                String cur = convertCurToBank(p_req1988.readedDetail.payCur);
                body.addChild(new XElement("currencyType", cur));
                String recAccount = p_req1988.readedDetail.recAct;
                body.addChild(new XElement("recAccount", recAccount));// 收方账户
                String recAccountName = p_req1988.readedDetail.recName;
                body.addChild(new XElement("recAccountName", recAccountName));// 收款方户名
                String recOpenBrn = p_req1988.readedDetail.cnapsCode;
                body.addChild(new XElement("recOpenBrn", recOpenBrn));// 收款方开户行行号
                String recOpenBrnName = p_req1988.readedDetail.cnapsName;
                body.addChild(new XElement("recOpenBrnName", recOpenBrnName));// 收款方开户行行名
                body.addChild(new XElement("recBrn", recOpenBrn));// 接收行号
                body.addChild(new XElement("recBrnName", recOpenBrnName));// 接受行名
                String transferAmt = p_req1988.readedDetail.payAmount;
                body.addChild(new XElement("transferAmt", transferAmt));// 交易金额
                body.addChild(new XElement("payUse", p_req1988.readedDetail.purpose));// 事由
                //是否加急
                body.addChild(new XElement("transferWay", p_req1988.readedDetail.paySpd));// 处理方式
                String tranType;
                if ("1".equals(p_req1988.readedDetail.sameBnk)) {
                    tranType = "00";
                } else {
                    //默认大额支付
                    tranType = "12";
                }
                body.addChild(new XElement("tranType", tranType));
                body.addChild(new XElement("payFee", ""));// 手续费
                body.addChild(new XElement("nextDayFlag", ""));// 次日到账标志
                //付款账号，付款方户名 付款账户开户机构 币种 收款账号 收款方户名
                //收款方开户行行号 收款方开户行名 接收行行号 接收行名 交易金额 交易类型
                String plain = p_req1988.readedDetail.payAct + p_req1988.readedDetail.payName + payAcctBrn +
                        cur + recAccount + recAccountName + recOpenBrn + recOpenBrnName + recOpenBrn + recOpenBrnName + transferAmt + tranType;
                String sign = MD5SaltHelper.md5Hex(plain);
                body.addChild(new XElement("MD5", sign));//
                nodeAnalysis(p_req1988.readedDetail.srcXElement, body, getCharset());
                xmlTextWriter.writeXElement(body);
                xmlTextWriter.writeEndDocument();
                String[] bankResult = sendToBank(xmlTextWriter.toXmlString());
                if (bankResult[0].length() == 0) {
                    StringBuilder tmpsbMsg = new StringBuilder();
                    XmlTextReader tmpbkReader = loadBankRespXmlReader(bankResult[1], tmpsbMsg);
                    if (tmpbkReader != null) {
                        int offset = bankResult[1].indexOf("<hostReturnCode>");
                        int endset = bankResult[1].indexOf("</hostReturnCode>") + "</hostReturnCode>".length();
                        String source = bankResult[1].substring(offset, endset);
                        offset = bankResult[1].indexOf("<hostErrorMessage>");
                        endset = bankResult[1].indexOf("</hostErrorMessage>") + "</hostErrorMessage>".length();
                        source = source + bankResult[1].substring(offset, endset);
                        String hostReturnEncrypt = tmpbkReader.getFirstText("/root/hostReturnEncrypt");
                        boolean b = PublickeyEncript.checkSign(source, hostReturnEncrypt, getBankConfig().getValueAsString("certificatePath"));
                        if (!b) {
                            respCode = "-1";
                            respInfo = "验签不通过";

                        } else {
                            String hostReturnCode = tmpbkReader.getFirstText("/root/hostReturnCode");
                            if (!"0000".equals(hostReturnCode)) {
                                respCode = "-1";
                                respInfo = tmpbkReader.getFirstText("/root/hostErrorMessage");
                            }
                        }
                    } else {
                        respCode = "-1";
                        respInfo = tmpsbMsg.toString();
                    }
                } else if (bankResult[0].equals(ConnState.FAIL)) {
                    JDBCHelper.update(conn, UPDATERECEIPT, new Object[]{ConnState.FAIL, "请求连接失败", p_req1988.readedDetail.askNumber, p_req1988.reqBatchNO});
                } else {
                    respCode = "-1";
                    respInfo = bankResult[1];
                }

            } catch (Exception ex) {
                respCode = "-1";
                respInfo = ex.getMessage();
                ex.printStackTrace();
            }
        }
        String context = reqseqIdContent.toString();
        if (StringHelper.hasAnyChar(context)) {
            FileHelper.writeFile(failpath, context, getCharset());
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        if ("-1".equals(respCode)) {
            retAts.respCode = "-1";
            retAts.respInfo = respInfo;
        } else {
            retAts.respCode = "0";
            retAts.transState = "0000";
            retAts.reqSeqID = p_req1988.reqBatchNO;
            retAts.payInfoCode = retAts.transState;
        }
        retAts.writeRetToATS();
        return retAts;
    }


    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        Connection conn = null;
        try {
            conn = FGBiz.getLocalDbConn();
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = "获取数据库连接失败，请检查数据库配置";
            retAts.writeBeforeDetail();
            retAts.writeEnd();
            return retAts;
        }

        retAts.respCode = "0";
        retAts.reqSeqID = p_req1998.reqBatchNO;
        // BANKREQSEQID,REQSEQID,STATE,ISFINISHED,RESERVE1 FROM REQSEQIDMAPPING
        List<Map<String, Object>> list = JDBCHelper.execQuery(conn, SELECTRECEIPT, new Object[]{p_req1998.reqBatchNO});
        WriteBankLogLn("该批次：" + p_req1998.reqBatchNO + "的支付笔数为：" + list.size());
        for (Map<String, Object> map : list) {
            RetAtsBatPayRecDetail detail = new RetAtsBatPayRecDetail();
            if ("1".equals(map.get("ISFINISHED"))) {
                detail.result = map.get("STATE").toString();
                detail.payInfoCode = detail.result;
                detail.postScript = map.get("REQSEQID").toString();
                detail.memo = map.get("RESERVE1").toString();
                retAts.writeRetDetail(detail);
                continue;
            }
            try {
                XmlTextWriter xmlTextWriter = new XmlTextWriter();
                JHBANK01Header header = new JHBANK01Header();
                header.userid = bankFront.operator;
                String nodeNo = getBankConfig().getValueAsString("nodeNo");
                header.brchno = nodeNo;
                header.servtp = "";
                header.prcscd = "QCA04";
                writeCommenHeader(xmlTextWriter, header);
                xmlTextWriter.writeStartElement("Body");
                xmlTextWriter.writeElementString("tellNo", bankFront.operator, true);
                xmlTextWriter.writeElementString("nodeNo", nodeNo, true);
                xmlTextWriter.writeElementString("tranCode", "QCA04", true);
                String transferFlowNo = map.get("BANKREQSEQID").toString();
                xmlTextWriter.writeElementString("transferFlowNo", transferFlowNo, true);
                xmlTextWriter.writeEndDocument();
                String[] bankResult = sendToBank(xmlTextWriter.toXmlString());
                if (bankResult[0].length() == 0) {
                    StringBuilder tmpsbMsg = new StringBuilder();
                    XmlTextReader tmpbkReader = loadBankRespXmlReader(bankResult[1], tmpsbMsg);
                    if (tmpbkReader != null) {
                        int offset = bankResult[1].indexOf("<hostReturnCode>");
                        int endset = bankResult[1].indexOf("</hostReturnCode>") + "</hostReturnCode>".length();
                        String source = bankResult[1].substring(offset, endset);
                        offset = bankResult[1].indexOf("<hostErrorMessage>");
                        endset = bankResult[1].indexOf("</hostErrorMessage>") + "</hostErrorMessage>".length();
                        source = source + bankResult[1].substring(offset, endset);
                        String hostReturnEncrypt = tmpbkReader.getFirstText("/root/hostReturnEncrypt");
                        boolean b = PublickeyEncript.checkSign(source, hostReturnEncrypt, getBankConfig().getValueAsString("certificatePath"));
                        if (!b) {
                            detail.result = "-1";
                            detail.payInfoCode = detail.result;
                            detail.memo = "验签不通过";
                        } else {
                            String hostReturnCode = tmpbkReader.getFirstText("/root/hostReturnCode");
                            String retMsg = tmpbkReader.getFirstText("/root/remark");
                            if (StringHelper.isNullOrEmpty(retMsg)) {
                                retMsg = tmpbkReader.getFirstText("/root/hostErrorMessage");
                            }
                            if ("0000".equals(hostReturnCode)) {
                                detail.result = tmpbkReader.getFirstText("/root/transt");
                                detail.payInfoCode = detail.result;
                                detail.postScript = map.get("REQSEQID").toString();
                                detail.memo = retMsg;// tmpbkReader.getFirstText("/root/remark");
                                if ("3".equals(detail.result) || "2".equals(detail.result)) {
                                    try {
                                        JDBCHelper.update(conn, UPDATERECEIPT, new Object[]{detail.result, detail.memo, map.get("REQSEQID"), p_req1998.reqBatchNO});
                                    } catch (Exception ex) {
                                        ex.printStackTrace();
                                    }
                                }
                            } else {
                                detail.result = hostReturnCode + "+" + tmpbkReader.getFirstText("/root/transt");
                                detail.payInfoCode = detail.result;
                                detail.postScript = map.get("REQSEQID").toString();
                                detail.memo = retMsg;//tmpbkReader.getFirstText("/root/hostErrorMessage");
                            }
                        }
                    } else {
                        detail.result = "-1";
                        detail.payInfoCode = detail.result;
                        detail.memo = tmpsbMsg.toString();
                    }
                } else {
                    detail.result = "-1";
                    detail.payInfoCode = detail.result;
                    detail.memo = bankResult[1];
                }
            } catch (Exception ex) {
                detail.result = "-1";
                detail.payInfoCode = detail.result;
                detail.memo = ex.getMessage();
                ex.printStackTrace();
            }
            retAts.writeRetDetail(detail);
        }
        String filePath = getBankConfig().getValueAsString("PayfailPath") + File.separator + p_req1998.reqBatchNO + ".txt";
        if (FileHelper.existFile(filePath)) {
            String context = FileHelper.readToString(new File(filePath), getCharset());
            if (StringHelper.hasAnyChar(context)) {
                String[] arr = context.split("\\|");
                for (String reqseqId : arr) {
                    RetAtsBatPayRecDetail detail = new RetAtsBatPayRecDetail();
                    detail.result = "dba_exp";
                    detail.payInfoCode = detail.result;
                    detail.postScript = reqseqId;
                    detail.memo = "插入数据库失败";
                    retAts.writeRetDetail(detail);

                }
            }
        }
        if (list == null && list.size() == 0) {
            retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
            retAts.respCode = "0";
            retAts.respInfo = "";
            retAts.transState = "";
            retAts.payInfoCode = "";
            retAts.reqSeqID = p_req1998.reqBatchNO;
            retAts.writeBeforeDetail();
        }
        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return null;
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return null;
    }
}
